﻿using CalligraphyWeb;
using CalligraphyWeb.Classes;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using ThuPhap.Models;

namespace Calligraphy.Models
{
    public class ItemControl
    {
        #region Data Members
        private itemControl data;
        public itemControl Data
        {
            get
            {
                if (data == null)
                    data = new itemControl();

                return data;
            }
            set
            {
                if (data == value) return;
                data = value;
            }
        }
        #endregion

        #region Class Methods
        public ItemControl()
        {
        }

        public ItemControl(int id, bool isLazy = true)
        {
            Get(id, isLazy);
        }

        public ItemControl(itemControl obj)
        {
            Get(obj);
        }

        public ItemControl(TextControlInfo ctrl)
        {
            Get(ctrl);
        }

        public ItemControl(templateControl templateCtrl)
        {
            Get(templateCtrl);
        }

        public ItemControl Get(int id, bool isLazy = true)
        {
            using (calligraphyEntities db = new calligraphyEntities())
            {
                db.Configuration.LazyLoadingEnabled = isLazy;
                var query = from c in db.itemControls
                            where c.id == id
                            select c;

                if (query.Count() > 0)
                {
                    var obj = query.FirstOrDefault();
                    return Get(obj);
                }
                else
                    return null;
            }
        }

        public ItemControl Get(itemControl obj)
        {
            if (this.data == obj) return this;

            this.data = obj;
            return this;
        }

        public ItemControl Get(TextControlInfo ctrl)
        {
            this.data = new itemControl()
            {
                id = 0,
                align = ctrl.Align,
                C_left = ctrl.Left,
                C_top = ctrl.Top,
                fontFamily = ctrl.FontFamily,
                fontSize = ctrl.FontSize,
                isBold = ctrl.IsBold,
                isItalic = ctrl.IsItalic,
                isSelected = ctrl.IsSelected,
                foreground = ctrl.Foreground,
                height = ctrl.Height,
                width = ctrl.Width,
                text = ctrl.Text,
                unicodeText = ctrl.UnicodeText,
                type = ctrl.Type
            };

            return this;
        }

        public ItemControl Get(templateControl ctrl)
        {
            if (ctrl == null) return null;
            this.data = new itemControl();

            this.data.id = 0;
            this.data.align = ctrl.align;
            this.data.C_left = ctrl.C_left;
            this.data.C_top = ctrl.C_top;
            this.data.fontFamily = ctrl.fontFamily;
            this.data.fontSize = ctrl.fontSize;
            this.data.foreground = ctrl.foreground;
            this.data.height = ctrl.height;
            this.data.isBold = ctrl.isBold;
            this.data.isItalic = ctrl.isItalic;
            this.data.isSelected = ctrl.isSelected;
            this.data.text = ctrl.text;
            this.data.type = ctrl.type;
            this.data.unicodeText = ctrl.unicodeText;
            this.data.width = ctrl.width;

            return this;

        }

        public templateControl ToTemplateControl()
        {
            TemplateControl temp = new TemplateControl(this.data);
            return temp.Data;
        }

        public TemplateControl ToTemplateControlInterface()
        {
            TemplateControl temp = new TemplateControl(this.data);
            return temp;
        }

        private long Insert()
        {
            ConvertVietnameseCode textConverter = new ConvertVietnameseCode();
            data.unicodeText = textConverter.VniWindowsToUnicode(data.text);

            using (calligraphyEntities db = new calligraphyEntities())
            {
                db.itemControls.Add(data);
                db.SaveChanges();
                return data.id;
            }
        }

        private long Update()
        {
            ConvertVietnameseCode textConverter = new ConvertVietnameseCode();
            data.unicodeText = textConverter.VniWindowsToUnicode(data.text);

            using (calligraphyEntities db = new calligraphyEntities())
            {
                db.itemControls.Attach(data);
                db.Entry(data).State = System.Data.EntityState.Modified;
                db.SaveChanges();
                return data.id;
            }
        }

        public long Save()
        {
            if (data.id == 0)
                return Insert();
            else
                return Update();
        }

        public long Delete()
        {
            using (calligraphyEntities db = new calligraphyEntities())
            {
                db.itemControls.Remove(data);
                db.SaveChanges();
                return data.id;
            }
        }
        #endregion

        #region Static Methods
        public static ObservableCollection<itemControl> Get(string sortColumn = "id", bool isAsc = false,
                                                    int pageIndex = 1, int pageSize = int.MaxValue,
                                                    bool isLazy = true)
        {
            using (calligraphyEntities db = new calligraphyEntities())
            {
                db.Configuration.LazyLoadingEnabled = isLazy;
                IQueryable<itemControl> query = db.itemControls.AsQueryable();


                query = Sorting(query, sortColumn, isAsc);
                query = Paging(query, pageIndex, pageSize);

                if (query == null)
                    return new ObservableCollection<itemControl>();
                else
                    return new ObservableCollection<itemControl>(query.ToList());
            }
        }

        public static List<long> Save(Collection<itemControl> collection)
        {
            var result = new List<long>();
            foreach (var obj in collection)
            {
                var temp = new ItemControl(obj);
                result.Add(temp.Save());
            }

            return result;
        }

        public static int Delete(Collection<itemControl> collection)
        {
            int result = 0;
            using (calligraphyEntities db = new calligraphyEntities())
            {
                foreach (var obj in collection)
                {
                    db.itemControls.Remove(obj);
                    result++;
                }

                db.SaveChanges();
            }
            return result;
        }

        public static string DeleteByItem(int itemID)
        { 
            using (calligraphyEntities db = new calligraphyEntities())
            {
                var data = from c in db.itemControls
                           where itemID.Equals(itemID)
                           select c;
                foreach (var iter in data)
                    db.itemControls.Remove(iter);

                db.SaveChanges();
            }
            return "";
        }

        private static IQueryable<itemControl> Sorting(IQueryable<itemControl> query, string sortColumn = "id", bool isAsc = false)
        {
            switch (sortColumn)
            {
                case "parent":
                    query = isAsc ? query.OrderBy(o => o.itemID) : query.OrderByDescending(o => o.itemID);
                    break;
                case "text":
                    query = isAsc ? query.OrderBy(o => o.text) : query.OrderByDescending(o => o.text);
                    break;
                case "unicode":
                    query = isAsc ? query.OrderBy(o => o.unicodeText) : query.OrderByDescending(o => o.unicodeText);
                    break;
                case "id":
                default:
                    query = isAsc ? query.OrderBy(o => o.id) : query.OrderByDescending(o => o.id);
                    break;
            }

            return query;
        }

        private static IQueryable<itemControl> Paging(IQueryable<itemControl> query, int pageIndex = 1, int pageSize = 10)
        {
            if (pageIndex <= 1)
                pageIndex = 0;
            else
                pageIndex--;

            return query.Skip(pageIndex * pageSize).Take(pageSize);
        }

        public static ObservableCollection<itemControl> Search(
                                        int parent = 0, string text = "", string unicodeText = "",
                                        string sortColumn = "id", bool isAsc = false,
                                        int pageIndex = 1, int pageSize = 10,
                                        bool isLazy = true)
        {
            using (calligraphyEntities db = new calligraphyEntities())
            {
                db.Configuration.LazyLoadingEnabled = isLazy;
                var query = from c in db.itemControls
                            where (string.IsNullOrEmpty(text) ? true : c.text.ToLower().Contains(text.ToLower()))
                            && (string.IsNullOrEmpty(unicodeText) ? true : c.unicodeText.ToLower().Contains(unicodeText.ToLower()))
                            && (parent == 0 ? true : c.itemID == parent)
                            select c;

                query = Sorting(query, sortColumn, isAsc);
                query = Paging(query, pageIndex, pageSize);

                if (query.Count() > 0)
                    return new ObservableCollection<itemControl>(query.ToList());
                else
                    return new ObservableCollection<itemControl>();
            }
        }
        #endregion
    }
}
